package cn.kilo.domain.service.infterface.impl;

import cn.kilo.domain.model.order.entity.*;
import cn.kilo.domain.model.order.res.*;
import cn.kilo.domain.model.order.vo.OrderStatusVO;
import cn.kilo.domain.repository.IStrategyRepository;
import cn.kilo.domain.service.infterface.IOrderStrategyService;
import cn.kilo.domain.service.infterface.IRoleJob;
import cn.kilo.domain.support.OssUploadService;
import cn.kilo.domain.support.QRCodeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author kilok
 */
@Service
@Slf4j
public class OrderStrategyService implements IOrderStrategyService {
    @Resource
    private IRoleJob roleJob;

    @Resource
    private OssUploadService ossUploadService;

    @Resource
    private IStrategyRepository repository;

    @Override
    public List<DepartmentRes> getDepartment() {
        return repository.getDepartment();
    }

    @Override
    public List<OrderStatusVO> performJob(OrderEntity orderEntity) {
        return roleJob.performJob(orderEntity);
    }

    @Override
    public String updateOrderPicture(Long orderId, MultipartFile image) throws IOException {
       String url=ossUploadService.uploadImg(image);
       repository.saveOrderInfoPicture(orderId,url);
       return url;
    }

    @Override
    public Collection<Object> queryGuardOrder(OrderEntity orderEntity) {
        return repository.queryGuardOrder(orderEntity);
    }

    @Override
    public List<OrderStatusVO> getOrderByQRCode(OrderEntity orderEntity) {
        String ridgepole =repository.getRidgepoleById(orderEntity.getGuard());
        orderEntity.setRidgepole(ridgepole);
        Collection<Object> objects  = repository.getOrderByQRCode(orderEntity);
        if(null==objects||objects.size()==0) {
            return null;
        }
        OrderEntity order=new OrderEntity();
        List<OrderStatusVO> orderStatusVOList =new ArrayList<>();
        for(Object orderStatusEntity:objects){
            BeanUtils.copyProperties(orderStatusEntity,order);
            order.setStatus("guard");
            order.setGuard(orderEntity.getGuard());
            log.info("orderInfoEntity:{}",order);
            orderStatusVOList.addAll(roleJob.performJob(order));
        }
        return orderStatusVOList;
    }

    @Override
    public Object[] getTokenOrder(OrderEntity orderEntity) {
        return repository.getTokenOrder(orderEntity);
    }

    @Override
    public int getCreateOrderByRidgepole(OrderEntity build) {
        return repository.getCreateOrderByRidgepole(build);
    }

    @Override
    public String updateOverPicture(MultipartFile image, Long orderId) throws IOException {
        String url=ossUploadService.uploadImg(image);
        repository.savePicture(url,orderId);
        return url;
    }

    @Override
    public List<OrderStatusVO> takeOrderFromGuard(OrderEntity orderEntity) {
        ReentrantLock lock=new ReentrantLock();
        try {
            boolean res = lock.tryLock(4, TimeUnit.SECONDS);
            if(res) {
                Collection<Object> orderStatusEntities = repository.takeOrderFromGuard(orderEntity);
                Object[] array = orderStatusEntities.toArray();
                if (null==orderStatusEntities||orderStatusEntities.size() == 0) {
                    return null;
                }
                if (orderEntity.getNumber() > orderStatusEntities.size()) {
                    return null;
                }
                List<OrderStatusVO> list = new ArrayList<>();
                for (int i = 0; i < orderEntity.getNumber(); i++) {
                    OrderEntity order = new OrderEntity();
                    BeanUtils.copyProperties(array[i], order);
                    repository.deleteOrderFromDepartment(order.getOrderId(),orderEntity.getRidgepole(),orderEntity.getEnd());
                    order.setStatus("sorter2");
                    order.setSorter2(orderEntity.getSorter2());
                    log.info("第二次接单orderEntity:{}", order);
                    list.addAll(roleJob.performJob(order));
                }
                return list;
            }
            return null;
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
    }

    @Override
    public Collection<Object> getOrderInfoList(OrderEntity build) {
        return repository.getOrderInfoList(build);
    }

    @Override
    public OrderStatusVO userGetOrderInfo(OrderEntity build) {
        return repository.userGetOrderInfo(build);
    }

    @Override
    public List<OrderStatusVO> getUserOrder(String userId, String status) {
        return  repository.getUserOrder(userId,status );
    }

    @Override
    public boolean JudgeOrder(OrderJudgeEntity orderJudgeEntity) {
        return  repository.judgeOrder(orderJudgeEntity);
    }

    /**
     * 自动为员工分配订单
     * @param ridgepole 楼栋
     * @param orderId 订单id
     */
    @Override
    public void offerOrderToStaff(String ridgepole, Long orderId) {
        String staffId=repository.getStaffIdByRidgepole(ridgepole);
        if(null==staffId){
            repository.setOrderError(orderId);
        }
        roleJob.performJob(OrderEntity.builder()
                        .orderId(orderId)
                        .sorter1(staffId)
                        .status("sorter1")
                .build());
    }

    @Override
    public String setWeather(String userId, String weather) {
        return repository.setWeather(userId,weather);
    }

    @Override
    public String getOrderNum() {
        return repository.getOrderNumber();
    }

    @Override
    public List<JudgeRes> getBadJudge(String type) {
        return repository.getBadJudge(type);
    }

    @Override
    public Map<String, Integer> getLeftStaff(OrderEntity orderEntity) {
        return roleJob.getLeftStaff(orderEntity);
    }

    @Override
    public List<DepartRes> getDepartmentGroup() {
       return repository.getDepartmentGroup();
    }

    @Override
    public List<String> getPosition() {
        return repository.getPosition();
    }

    @Override
    public void getPayInfo() {

    }

    @Override
    public List<FloorRes> getFloor(String ridgepole) {
        return repository.getFloorByRidgepole(ridgepole);
    }

    @Override
    public StaffRes getStaff(String staffId) {
        return repository.getStaff(staffId);
    }

    @Override
    public String updateORCode(MultipartFile multipartFile) throws IOException {
        QRCodeUtils.deleteFile("filename.png");
        String url = ossUploadService.uploadImgByExpiration(multipartFile);
        return url;
    }

    @Override
    public Long getAllSalary() {
        return repository.getAllSalary();
    }

    @Override
    public Long getMonthSalary() {
        return repository.getMonthSalary();
    }

    @Override
    public Integer getUserNumber() {
        return repository.getUserNumber();
    }

    @Override
    public Integer getMothUser() {
        return repository.getMothUser();
    }

    @Override
    public Long getAllMoney() {
        return repository.getAllMoney();
    }

    @Override
    public Long getMothMoney() {
        return repository.getMothMoney();
    }

    @Override
    public Long getAllOutcome() {
        return repository.getAllOutcome();
    }

    @Override
    public Long getMothOutcome() {
        return repository.getMothOutcome();
    }

    @Override
    public List<MUserRes> getAllUsers() {
        return repository.getAllUsers();
    }

    @Override
    public List<MUserRes> getUserBy(MUserEntity build) {

        return repository.getUserBy(build);
    }

    @Override
    public List<MRiderRes> getAllRider() {
        return repository.getAllRider();
    }

    @Override
    public List<MRiderRes> getRiderBy(MRiderEntity build) {
        return repository.getRiderBy(build);
    }

    @Override
    public List<MGuardRes> getAllGuard() {
        return repository.getAllGuard();
    }

    @Override
    public List<MGuardRes> getGuardBy(MGuardEntity build) {
        return repository.getGuardBy(build);
    }

    @Override
    public List<MSorterRes> getAllSorter() {
        return repository.getAllSorter();
    }

    @Override
    public List<MSorterRes> getSorterBy(MSorterEntity build) {
        return repository.getSorterBy(build);
    }


}
